﻿/*
 * EmeCoder v1.2.1.168
 * 作者：Administrator/PC4APPLE
 * 时间：2013-06-03 16:29:59
 * 版权：版权所有 (C) Eme Development Team 2013
*/

﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using HmFramework.Data;
using CuteSprite.Eme.Data.BsdUserCenter;

namespace CuteSprite.Eme.Data.CRM
{
	/// <summary>富力经济线快件</summary>
	[Serializable]
	[ModelCheckMode(ModelCheckModes.CheckTableWhenFirstUse)]
	public class ExpressEconomyLine : ExpressEconomyLine<ExpressEconomyLine> { }

	/// <summary>富力经济线快件</summary>
	public partial class ExpressEconomyLine<TEntity> : Entity<TEntity> where TEntity : ExpressEconomyLine<TEntity>, new()
	{
		#region 对象操作﻿

		static ExpressEconomyLine()
		{
			// 用于引发基类的静态构造函数，所有层次的泛型实体类都应该有一个
			TEntity entity = new TEntity();
		}

		/// <summary>验证数据，通过抛出异常的方式提示验证失败。</summary>
		/// <param name="isNew"></param>
		public override void Valid(Boolean isNew)
		{
			// 这里验证参数范围，建议抛出参数异常，指定参数名，前端用户界面可以捕获参数异常并聚焦到对应的参数输入框
			//if (MatchHelper.StrIsNullOrEmpty(Name)) throw new ArgumentNullException(_.Name, _.Name.DisplayName + "无效！");
			//if (!isNew && ID < 1) throw new ArgumentOutOfRangeException(_.ID, _.ID.DisplayName + "必须大于0！");

			// 建议先调用基类方法，基类方法会对唯一索引的数据进行验证
			base.Valid(isNew);

			// 在新插入数据或者修改了指定字段时进行唯一性验证，CheckExist内部抛出参数异常
			//if (isNew || Dirtys[__.Name]) CheckExist(__.Name);

			// 货币保留6位小数
			if (Dirtys[__.ActualWeight]) ActualWeight = Math.Round(ActualWeight, 6);
			// 货币保留6位小数
			if (Dirtys[__.ChargeableWeight]) ChargeableWeight = Math.Round(ChargeableWeight, 6);
			// 货币保留6位小数
			if (Dirtys[__.DeclaredValue]) DeclaredValue = Math.Round(DeclaredValue, 6);
			// 货币保留6位小数
			if (Dirtys[__.CollectAmount]) CollectAmount = Math.Round(CollectAmount, 6);
			// 货币保留6位小数
			if (Dirtys[__.InsurancePrice]) InsurancePrice = Math.Round(InsurancePrice, 6);
			// 货币保留6位小数
			if (Dirtys[__.SettleWeight]) SettleWeight = Math.Round(SettleWeight, 6);
			// 货币保留6位小数
			if (Dirtys[__.SettleVolWeight]) SettleVolWeight = Math.Round(SettleVolWeight, 6);
			// 货币保留6位小数
			if (Dirtys[__.ReceWeight]) ReceWeight = Math.Round(ReceWeight, 6);
			// 货币保留6位小数
			if (Dirtys[__.ReceVolWeight]) ReceVolWeight = Math.Round(ReceVolWeight, 6);
			// 货币保留6位小数
			if (Dirtys[__.ProfitWeight]) ProfitWeight = Math.Round(ProfitWeight, 6);
			// 货币保留6位小数
			if (Dirtys[__.ProfitVolWeight]) ProfitVolWeight = Math.Round(ProfitVolWeight, 6);

			if (isNew)
			{
				//if (!Dirtys[__.CreateOn]) { CreateOn = DateTime.Now; }
				CreateOn = DateTime.Now;
			}
			else if (HasDirty)
			{
				//if (!Dirtys[__.ModifiedOn]) { ModifiedOn = DateTime.Now; }
				ModifiedOn = DateTime.Now;
			}
		}

		/// <summary>已重载。删除关联数据</summary>
		/// <returns></returns>
		protected override int OnDelete()
		{
			if (ExpressEconomyLineRecipients != null) { ExpressEconomyLineRecipients.Delete(); }
			if (ExpressEconomyLineSends != null) { ExpressEconomyLineSends.Delete(); }
			if (ExpressEconomyLineStatuses != null) { ExpressEconomyLineStatuses.Delete(); }

			return base.OnDelete();
		}

		/// <summary>已重载。插入数据</summary>
		/// <returns></returns>
		protected override int OnInsert()
		{
			if (EntityHelper.IsORMRemoting) { return base.OnInsert(); }

			if (OperationStatus.IsNullOrWhiteSpace()) { OperationStatus = "已揽件"; }

			// 根据寄件公司名称自动匹配客户
			AutoFindCustomer();

			var rs = base.OnInsert();

			var status = new ExpressEconomyLineStatus();
			status.ExpressMixID = ID;
			status.ExpressType = ExpressType;
			status.CWBNo = CWBNo;
			status.OriginNo = OriginNo;
			status.OrganizeID = OrganizeID;
			status.CustomerID = CustomerID;
			status.OperationStatus = "已揽件";
			status.Description = "已从寄件人处揽件";
			//status.OperationTime = DateTime.Now;

			//// 以揽件状态的操作时间由快件的收件日期加上系统当前时间组成
			//status.OperationTime = DateTime.Parse("{0:yyyy-MM-dd} {1:HH:mm:s}".FormatWith(ExpressDate, DateTime.Now));

			status.OperationTime = ExpressDate;

			var recs = ExpressEconomyLineRecipients;
			if (recs != null && recs.Count > 0)
			{
				var rec = recs[0];
				status.OperationOrganizeID = rec.OrganizeID;
				status.OperationStaffID = rec.StaffID;
			}
			status.IsCompleted = 0;
			status.ModifiedBy = "Administrator";
			status.ModifiedOn = DateTime.Now;
			status.ModifiedUserID = 1;
			status.CreateOn = DateTime.Now;
			status.CreateBy = "Administrator";
			status.CreateUserID = 1;
			status.Save();

			return rs;
		}

		/// <summary>已重载。更新数据</summary>
		protected override int OnUpdate()
		{
			// 根据寄件公司名称自动匹配客户
			AutoFindCustomer();

			var rs = base.OnUpdate();

			var es = ExpressEconomyLineStatuses;
			if (es != null && es.Count > 0)
			{
				foreach (var item in es)
				{
					item.ExpressType = ExpressType;
					item.CWBNo = CWBNo;
					item.OriginNo = OriginNo;
					item.OrganizeID = OrganizeID;
					item.CustomerID = CustomerID;
					switch (item.OperationStatus)
					{
						case "已揽件":
							var recs = ExpressEconomyLineRecipients;
							if (recs != null && recs.Count > 0)
							{
								var rec = recs[0];
								item.OperationOrganizeID = rec.OrganizeID;
								item.OperationStaffID = rec.StaffID;
							}
							else
							{
								item.OperationOrganizeID = 0;
								item.OperationStaffID = 0;
							}
							break;

						case "派送中":
						case "已签收":
							var sends = ExpressEconomyLineSends;
							if (sends != null && sends.Count > 0)
							{
								var send = sends[0];
								item.OperationOrganizeID = send.OrganizeID;
								item.OperationStaffID = send.StaffID;
							}
							else
							{
								item.OperationOrganizeID = 0;
								item.OperationStaffID = 0;
							}
							break;

						default:
							break;
					}
					if ("已签收" == item.OperationStatus && !SignedPerson.IsNullOrWhiteSpace())
					{
						item.SignedPerson = SignedPerson;
					}
					item.Save();
				}
			}

			return rs;
		}

		/// <summary>客户、部门自动匹配</summary>
		private void AutoFindCustomer()
		{
			// 根据寄件公司名称自动匹配客户
			if (CustomerID <= 0 && !ShipperName.IsNullOrWhiteSpace())
			{
				var customer = BsdCustomer.FindByName(ShipperName);
				if (customer == null) { customer = BsdCustomer.FindByNameEN(ShipperName); }
				if (customer == null) { customer = BsdCustomer.FindByNameEN2(ShipperName); }
				if (customer != null)
				{
					CustomerID = customer.ID;
					// 如果没有选择部门则自动匹配部门
					if (OrganizeID <= 0) { OrganizeID = customer.OrganizeID; }
				}
			}
			else
			{
				// 所属客户不为空，所属部门为空，部门自动填充客户所属部门
				if (OrganizeID <= 0)
				{
					var customer = BsdCustomer.FindByID(CustomerID);
					if (customer != null) { OrganizeID = customer.OrganizeID; }
				}
			}
		}

		#endregion

		#region 扩展属性﻿

		/// <summary>该富力经济线快件所属部门</summary>
		[XmlIgnore]
		public BsdOrganize Organize
		{
			get { return Extends.GetExtend<BsdOrganize, BsdOrganize>("Organize", e => BsdOrganize.FindByID(OrganizeID)); }
			set { Extends.SetExtend<BsdOrganize>("Organize", value); }
		}

		private String _Extend_OrganizeID;

		/// <summary>所属部门显示名称</summary>
		public String Extend_OrganizeID
		{
			get
			{
				if (EntityHelper.IsORMRemoting)
				{
					return _Extend_OrganizeID;
				}
				else
				{
					if (Organize != null) { return Organize.FullName; } else { return null; }
				}
			}
			set { _Extend_OrganizeID = value; }
		}

		/// <summary>该富力经济线快件所属客户</summary>
		[XmlIgnore]
		public BsdCustomer Customer
		{
			get { return Extends.GetExtend<BsdCustomer, BsdCustomer>("Customer", e => BsdCustomer.FindByID(CustomerID)); }
			set { Extends.SetExtend<BsdCustomer>("Customer", value); }
		}

		private String _Extend_CustomerID;

		/// <summary>所属客户显示名称</summary>
		public String Extend_CustomerID
		{
			get
			{
				if (EntityHelper.IsORMRemoting)
				{
					return _Extend_CustomerID;
				}
				else
				{
					if (Customer != null) { return Customer.Name; } else { return null; }
				}
			}
			set { _Extend_CustomerID = value; }
		}

		//[NonSerialized]
		//private EntityList<ExpressEconomyLineStatus> _ExpressStatuss;
		/// <summary>该富力经济线快件所拥有的快件状态集合</summary>
		[XmlIgnore]
		public EntityList<ExpressEconomyLineStatus> ExpressEconomyLineStatuses
		{
			get
			{
				return Extends.GetExtend<ExpressEconomyLineStatus, EntityList<ExpressEconomyLineStatus>>("ExpressEconomyLineStatuses", es => ExpressEconomyLineStatus.FindAllByExpressMixID(ID));
				//if (_ExpressStatuss == null && ID > 0 && !Dirtys.ContainsKey("ExpressStatuss"))
				//{
				//	_ExpressStatuss = ExpressEconomyLineStatus.FindAllByExpressMixID(ID);
				//	Dirtys["ExpressStatuss"] = true;
				//}
				//return _ExpressStatuss;
			}
			set { Extends.SetExtend<ExpressEconomyLineStatus>("ExpressEconomyLineStatuses", value); }
		}

		//[NonSerialized]
		//private EntityList<ExpressEconomyLineRecipient> _ExpressMixRecipients;
		/// <summary>该富力经济线快件所拥有的富力经济线快件揽件员工集合</summary>
		[XmlIgnore]
		public EntityList<ExpressEconomyLineRecipient> ExpressEconomyLineRecipients
		{
			get
			{
				return Extends.GetExtend<ExpressEconomyLineRecipient, EntityList<ExpressEconomyLineRecipient>>("ExpressEconomyLineRecipients", es => ExpressEconomyLineRecipient.FindAllByExpressID(ID));
				//if (_ExpressMixRecipients == null && ID > 0 && !Dirtys.ContainsKey("ExpressEconomyLineRecipients"))
				//{
				//	_ExpressMixRecipients = ExpressEconomyLineRecipient.FindAllByExpressID(ID);
				//	Dirtys["ExpressEconomyLineRecipients"] = true;
				//}
				//return _ExpressMixRecipients;
			}
			set { Extends.SetExtend<ExpressEconomyLineRecipient>("ExpressEconomyLineRecipients", value); }
		}

		private String _Extend_ExpressRecipientStaffIDs;

		/// <summary>该客户快件所拥有的快件揽件员工ID</summary>
		public String Extend_ExpressRecipientStaffIDs
		{
			get
			{
				if (EntityHelper.IsORMRemoting)
				{
					return _Extend_ExpressRecipientStaffIDs;
				}
				else
				{
					var recs = ExpressEconomyLineRecipients;
					if (recs != null && recs.Count > 0)
					{
						return String.Join(",", recs.ToList().Select(e => e.StaffID).ToList().ConvertAll(e => "" + e).ToArray());
					}
					else { return null; }
				}
			}
			set { _Extend_ExpressRecipientStaffIDs = value; }
		}

		private String _Extend_ExpressRecipientStaffNames;

		/// <summary>该客户快件所拥有的快件揽件员工名称</summary>
		public String Extend_ExpressRecipientStaffNames
		{
			get
			{
				if (EntityHelper.IsORMRemoting)
				{
					return _Extend_ExpressRecipientStaffNames;
				}
				else
				{
					var recs = ExpressEconomyLineRecipients;
					if (recs != null && recs.Count > 0)
					{
						var list = recs.ToList().Select(e => e.StaffID).ToList();
						var sb = new StringBuilder();
						foreach (var item in list)
						{
							var staff = BsdStaff.FindByID(item);
							if (staff == null) { continue; }
							if (sb.Length > 0) { sb.Append(","); }
							sb.Append(staff.FullName);
						}
						return sb.ToString();
					}
					else { return null; }
				}
			}
			set { _Extend_ExpressRecipientStaffNames = value; }
		}

		//[NonSerialized]
		//private EntityList<ExpressEconomyLineSend> _ExpressMixSends;
		/// <summary>该富力经济线快件所拥有的富力经济线快件派件员工集合</summary>
		[XmlIgnore]
		public EntityList<ExpressEconomyLineSend> ExpressEconomyLineSends
		{
			get
			{
				return Extends.GetExtend<ExpressEconomyLineSend, EntityList<ExpressEconomyLineSend>>("ExpressEconomyLineSends", es => ExpressEconomyLineSend.FindAllByExpressID(ID));
				//if (_ExpressMixSends == null && ID > 0 && !Dirtys.ContainsKey("ExpressMixSends"))
				//{
				//	_ExpressMixSends = ExpressEconomyLineSend.FindAllByExpressID(ID);
				//	Dirtys["ExpressMixSends"] = true;
				//}
				//return _ExpressMixSends;
			}
			set { Extends.SetExtend<ExpressEconomyLineSend>("ExpressEconomyLineSends", value); }
		}

		private String _Extend_ExpressSendStaffIDs;

		/// <summary>该客户快件所拥有的快件派件员工ID</summary>
		public String Extend_ExpressSendStaffIDs
		{
			get
			{
				if (EntityHelper.IsORMRemoting)
				{
					return _Extend_ExpressSendStaffIDs;
				}
				else
				{
					var sends = ExpressEconomyLineSends;
					if (sends != null && sends.Count > 0)
					{
						return String.Join(",", sends.ToList().Select(e => e.StaffID).ToList().ConvertAll(e => "" + e).ToArray());
					}
					else { return null; }
				}
			}
			set { _Extend_ExpressSendStaffIDs = value; }
		}

		private String _Extend_ExpressSendStaffNames;

		/// <summary>该客户快件所拥有的快件派件员工名称</summary>
		public String Extend_ExpressSendStaffNames
		{
			get
			{
				if (EntityHelper.IsORMRemoting)
				{
					return _Extend_ExpressSendStaffNames;
				}
				else
				{
					var sends = ExpressEconomyLineSends;
					if (sends != null && sends.Count > 0)
					{
						var list = sends.ToList().Select(e => e.StaffID).ToList();
						var sb = new StringBuilder();
						foreach (var item in list)
						{
							var staff = BsdStaff.FindByID(item);
							if (staff == null) { continue; }
							if (sb.Length > 0) { sb.Append(","); }
							sb.Append(staff.FullName);
						}
						return sb.ToString();
					}
					else { return null; }
				}
			}
			set { _Extend_ExpressSendStaffNames = value; }
		}

		#endregion

		#region 扩展查询﻿

		/// <summary>根据所属部门、快递方式查找</summary>
		/// <param name="expresstype">快递方式</param>
		/// <param name="organizeid">所属部门</param>
		/// <returns></returns>
		[DataObjectMethod(DataObjectMethodType.Select, false)]
		public static EntityList<TEntity> FindAllByOrganizeIDAndExpressType(String expresstype, Int32 organizeid)
		{
			if (Meta.Count > 1000)
				return FindAll(new String[] { _.ExpressType, _.OrganizeID }, new Object[] { expresstype, organizeid });
			else // 实体缓存
				return Meta.Cache.Entities.FindAll(e => e.ExpressType == expresstype && e.OrganizeID == organizeid);
		}

		/// <summary>根据主键查找</summary>
		/// <param name="id">主键</param>
		/// <returns></returns>
		[DataObjectMethod(DataObjectMethodType.Select, false)]
		public static TEntity FindByID(Int32 id)
		{
			if (Meta.Count > 1000)
				return Find(_.ID, id);
			else // 实体缓存
				return Meta.Cache.Entities.Find(_.ID, id);
			// 单对象缓存
			//return Meta.SingleCache[id];
		}

		/// <summary>根据创建用户ID查找</summary>
		/// <param name="createuserid">创建用户ID</param>
		/// <returns></returns>
		[DataObjectMethod(DataObjectMethodType.Select, false)]
		public static EntityList<TEntity> FindAllByCreateUserID(Int32 createuserid)
		{
			if (Meta.Count > 1000)
				return FindAll(_.CreateUserID, createuserid);
			else // 实体缓存
				return Meta.Cache.Entities.FindAll(_.CreateUserID, createuserid);
		}

		/// <summary>根据运单号查找</summary>
		/// <param name="cwbno">运单号</param>
		/// <returns></returns>
		[DataObjectMethod(DataObjectMethodType.Select, false)]
		public static TEntity FindByCWBNo(String cwbno)
		{
			if (Meta.Count > 1000)
				return Find(_.CWBNo, cwbno);
			else // 实体缓存
				return Meta.Cache.Entities.Find(_.CWBNo, cwbno);
			// 单对象缓存
			//return Meta.SingleCache[cwbno];
		}

		/// <summary>根据所属部门查找</summary>
		/// <param name="organizeid">所属部门</param>
		/// <returns></returns>
		[DataObjectMethod(DataObjectMethodType.Select, false)]
		public static EntityList<TEntity> FindAllByOrganizeID(Int32 organizeid)
		{
			if (Meta.Count > 1000)
				return FindAll(_.OrganizeID, organizeid);
			else // 实体缓存
				return Meta.Cache.Entities.FindAll(_.OrganizeID, organizeid);
		}

		/// <summary>根据所属客户查找</summary>
		/// <param name="customerid">所属客户</param>
		/// <returns></returns>
		[DataObjectMethod(DataObjectMethodType.Select, false)]
		public static EntityList<TEntity> FindAllByCustomerID(Int32 customerid)
		{
			if (Meta.Count > 1000)
				return FindAll(_.CustomerID, customerid);
			else // 实体缓存
				return Meta.Cache.Entities.FindAll(_.CustomerID, customerid);
		}

		#endregion

		#region 高级查询

		// 以下为自定义高级查询的例子

		///// <summary>
		///// 查询满足条件的记录集，分页、排序
		///// </summary>
		///// <param name="key">关键字</param>
		///// <param name="orderClause">排序，不带Order By</param>
		///// <param name="startRowIndex">开始行，0表示第一行</param>
		///// <param name="maximumRows">最大返回行数，0表示所有行</param>
		///// <returns>实体集</returns>
		//[DataObjectMethod(DataObjectMethodType.Select, true)]
		//public static EntityList<TEntity> Search(String key, String orderClause, Int32 startRowIndex, Int32 maximumRows)
		//{
		//    return FindAll(SearchWhere(key), orderClause, null, startRowIndex, maximumRows);
		//}

		///// <summary>
		///// 查询满足条件的记录总数，分页和排序无效，带参数是因为ObjectDataSource要求它跟Search统一
		///// </summary>
		///// <param name="key">关键字</param>
		///// <param name="orderClause">排序，不带Order By</param>
		///// <param name="startRowIndex">开始行，0表示第一行</param>
		///// <param name="maximumRows">最大返回行数，0表示所有行</param>
		///// <returns>记录数</returns>
		//public static Int32 SearchCount(String key, String orderClause, Int32 startRowIndex, Int32 maximumRows)
		//{
		//    return FindCount(SearchWhere(key), null, null, 0, 0);
		//}

		///// <summary>构造搜索条件</summary>
		///// <param name="key">关键字</param>
		///// <returns></returns>
		//private static String SearchWhere(String key)
		//{
		//	// WhereExpression重载&和|运算符，作为And和Or的替代
		//	// SearchWhereByKeys系列方法用于构建针对字符串字段的模糊搜索
		//	var exp = SearchWhereByKeys(key, null);

		//	// 以下仅为演示，Field（继承自FieldItem）重载了==、!=、>、<、>=、<=等运算符（第4行）
		//	//if (userid > 0) exp &= _.OperatorID == userid;
		//	//if (isSign != null) exp &= _.IsSign == isSign.Value;
		//	//if (start > DateTime.MinValue) exp &= _.OccurTime >= start;
		//	//if (end > DateTime.MinValue) exp &= _.OccurTime < end.AddDays(1).Date;

		//	return exp;
		//}

		#endregion

		#region 扩展操作

		#endregion

		#region 业务

		/// <summary>根据运单号码，检查运单是否已经输入</summary>
		/// <param name="expressNo"></param>
		/// <param name="excludedID"></param>
		/// <returns></returns>
		public static Boolean CheckExpressNoIsExist(String expressNo, Int32 excludedID)
		{
			TEntity express = null;
			if (excludedID > 0)
			{
				express = Find(_.CWBNo.Equal(expressNo) & _.ID.NotEqual(excludedID));
			}
			else
			{
				express = FindByCWBNo(expressNo);
			}
			return express != null;
		}

		#region 格式化重量

		/// <summary>格式化重量</summary>
		/// <param name="weight"></param>
		/// <returns></returns>
		public static Decimal FormatWeight(Decimal weight)
		{
			if (weight > 30M)
			{
				return Math.Ceiling(weight);
			}
			else
			{
				var v = Math.Truncate(weight);
				var mod = weight % 1;
				if (v > 0M)
				{
					if (mod == 0M)
					{
						return v;
					}
					else
					{
						if (mod > 0.5M)
						{
							return Math.Ceiling(weight);
						}
						else
						{
							return v + 0.5M;
						}
					}
				}
				else
				{
					if (mod > 0.5M)
					{
						return Math.Ceiling(weight);
					}
					else
					{
						return 0.5M;
					}
				}
			}
		}

		#endregion

		#endregion
	}
}